
#include "stdafx.h"
#include "SceneContructor_Util.h"
#include "GeomTreeTraverseUtil.h"
#include "Dat_2_File_Op.h"
#include "osg/Geode"
#include "../GeomStructure.h"
#include "osg/Geometry"
#include "osgUtil/SmoothingVisitor"
#include "GeomNode.h"


void SceneConstructor_Util::ClasifyProductByName( const std::vector<std::string>& vStrName, std::map<std::string, std::vector<std::string>>& mapProduct, bool bDatIsIncluded/* = true*/ )
{
	std::map<std::string, std::vector<std::string>>::iterator itMap;
	if( bDatIsIncluded )
	{
		for( size_t i = 0; i < vStrName.size(); ++ i )
		{
			string strNameT = GeomTreeTraverseUtil::NodeNameToProductName( vStrName[ i ] );
			string strName( strNameT.begin(), strNameT.end() - 4 ); 
			itMap = mapProduct.find( strName );
			if( itMap == mapProduct.end() )
				mapProduct.insert( std::make_pair( strName, vector<string>( 1, vStrName[ i ] ) ) );
			else
				itMap->second.push_back( vStrName[ i ] );
		}
	}
	else
	{
		for( size_t i = 0; i < vStrName.size(); ++ i )
		{
			string strName = GeomTreeTraverseUtil::NodeNameToProductName( vStrName[ i ] );
			//string strName( strNameT.begin(), strNameT.end() - 4 ); 
			itMap = mapProduct.find( strName );
			if( itMap == mapProduct.end() )
				mapProduct.insert( std::make_pair( strName, vector<string>( 1, vStrName[ i ] ) ) );
			else
				itMap->second.push_back( vStrName[ i ] );
		}
	}
}

void SceneConstructor_Util::ConstructSceneFromFile( const char* lpszPath, const std::map<std::string, std::vector<std::string>>& mapProduct, osg::ref_ptr<osg::Switch> pPrjOSG, shared_ptr<CGeomNode>& pPrjTree, bool bDatIsIncluded/* = true*/ )
{
	pPrjOSG->removeChildren( 0, pPrjOSG->getNumChildren() );
	std::map<std::string, std::vector<std::string>>::const_iterator itMap = mapProduct.begin();

	string strFileExt = "";
	if( !bDatIsIncluded )
		strFileExt = ".dat";
	
	for( int iColor = 0; itMap != mapProduct.end(); ++ itMap, ++ iColor )
	{
		osg::Vec4 clr;
		GeomStructure::RandomColor( iColor, clr );
		osg::ref_ptr<osg::Switch> pClass( new osg::Switch() );
		string strTem = itMap->first.c_str();
		pClass->setName( itMap->first.c_str() );

		//strTem = pClass->getName();

		shared_ptr<CGeomNode> pClassT( new CGeomNode( itMap->first, pClass ) );
		
		const vector<string>&	vStrProduct = itMap->second;
		for( size_t i = 0; i < vStrProduct.size(); ++ i )
		{
			vector<vector<PT3D>> vvPT;
			vector<vector<int>> vvTriIdx;
			string strProductFileName = string( lpszPath )  + "\\"  + vStrProduct[ i ] + strFileExt;
			CDat_2_File_OP::LoadBK_2Meshes( strProductFileName.c_str(), vvPT, vvTriIdx );
			if( vvTriIdx.empty() )
				continue;

			osg::ref_ptr<osg::Switch> pProduct( new osg::Switch() );
			pProduct->setName( vStrProduct[ i ].c_str() );

			shared_ptr<CGeomNode> pProductT( new CGeomNode( vStrProduct[ i ], pProduct ) );

			CreateProduct( vvPT, vvTriIdx, pProduct, pProductT, lpszPath, clr );

			pClass->addChild( pProduct.get() );

			pClassT->AddChild( pProductT );

		}
		pPrjOSG->addChild( pClass.get() );

		pPrjTree->AddChild( pClassT );
	}
}

void SceneConstructor_Util::CreateProduct( const vector<vector<PT3D>>& vvPT, const vector<vector<int>>& vvTriIdx, osg::ref_ptr<osg::Switch> pProductOSG, shared_ptr<CGeomNode>& pProductTree, const char* lpszPath, osg::Vec4& clr )
{
	

	char cBuf[ 10 ];
	for( size_t i = 0; i < vvPT.size(); ++ i )
	{
		const vector<PT3D>& vPT = vvPT[ i ];
		const vector<int>& vIdx = vvTriIdx[ i ];
		osg::ref_ptr<osg::Switch> pMesh( new osg::Switch() );
		itoa( i, cBuf, 10 );
		string strMeshName = "MeshItem " + string( cBuf );
		pMesh->setName( strMeshName.c_str() );

		shared_ptr<CGeomNode> pMeshT( new CGeomNode( strMeshName, pMesh ) );

		osg::ref_ptr<osg::Vec3Array> pAry( new osg::Vec3Array );
		for( size_t j = 0; j < vPT.size(); ++ j )
			pAry->push_back( osg::Vec3( vPT[ j ].x, vPT[ j ].y, vPT[ j ].z ) );

		osg::ref_ptr<osg::DrawElementsUShort> triFace( new osg::DrawElementsUShort( GL_TRIANGLES, 0 ) );
		for( size_t j = 0; j < vIdx.size(); ++ j )
			triFace->push_back( vIdx[ j ] );

		/*osg::Vec4 clr0;
		GeomStructure::RandomColor( i, clr0 );*/
		osg::ref_ptr<osg::Vec4Array> pClrAry( new osg::Vec4Array );
		pClrAry->push_back( clr );

		osg::ref_ptr<osg::Geometry>	pGeometry( new osg::Geometry );
		pGeometry->setVertexArray( pAry.get() );
		pGeometry->addPrimitiveSet( triFace.get() );
		pGeometry->setColorArray( pClrAry.get() );
		pGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );

		osgUtil::SmoothingVisitor::smooth( *pGeometry );
		osg::ref_ptr<osg::Geode> pLeafNode( new osg::Geode );
		pLeafNode->setName( "Leaf" );
		pLeafNode->addDrawable( pGeometry );
		pMesh->addChild( pLeafNode.get() );

		pProductOSG->addChild( pMesh.get() );

		pProductTree->AddChild( pMeshT );
	}	
}



void SceneConstructor_Util::ConstructSceneFromFile( const char* lpszPath, const std::map<std::string, std::vector<std::string>>& mapProduct, osg::ref_ptr<osg::Switch> pPrjOSG )
{
	//pPrjOSG->removeChildren( 0, pPrjOSG->getNumChildren() );
	//std::map<std::string, std::vector<std::string>>::const_iterator itMap = mapProduct.begin();

	//for( int iColor = 0; itMap != mapProduct.end(); ++ itMap, ++ iColor )
	//{
	//	osg::Vec4 clr;
	//	GeomStructure::RandomColor( iColor, clr );
	//	osg::ref_ptr<osg::Switch> pClass( new osg::Switch() );
	//	string strTem = itMap->first.c_str();
	//	pClass->setName( itMap->first.c_str() );

	//	//shared_ptr<CGeomNode> pClassT( new CGeomNode( pClass->getName() ) );

	//	const vector<string>&	vStrProduct = itMap->second;
	//	for( size_t i = 0; i < vStrProduct.size(); ++ i )
	//	{
	//		vector<vector<PT3D>> vvPT;
	//		vector<vector<int>> vvTriIdx;
	//		string strProductFileName = string( lpszPath )  + "\\"  + vStrProduct[ i ];
	//		CDat_2_File_OP::LoadBK_2Meshes( strProductFileName.c_str(), vvPT, vvTriIdx );
	//		if( vvTriIdx.empty() )
	//			continue;

	//		osg::ref_ptr<osg::Switch> pProduct( new osg::Switch() );
	//		pProduct->setName( vStrProduct[ i ].c_str() );

	//		//shared_ptr<CGeomNode> pProductT( new CGeomNode( pProduct->getName() ) );

	//		CreateProduct( vvPT, vvTriIdx, pProduct, lpszPath, clr );

	//		pClass->addChild( pProduct.get() );

	//		//pClassT->AddChild( pProductT );

	//	}
	//	pPrjOSG->addChild( pClass.get() );

	//	//pPrjTree->AddChild( pClassT );
	//}
}

void SceneConstructor_Util::CreateProduct( const vector<vector<PT3D>>& vvPT, const vector<vector<int>>& vvTriIdx, osg::ref_ptr<osg::Switch> pProductOSG, const char* lpszPath, osg::Vec4& clr )
{


	//char cBuf[ 10 ];
	//for( size_t i = 0; i < vvPT.size(); ++ i )
	//{
	//	const vector<PT3D>& vPT = vvPT[ i ];
	//	const vector<int>& vIdx = vvTriIdx[ i ];
	//	osg::ref_ptr<osg::Switch> pMesh( new osg::Switch() );
	//	itoa( i, cBuf, 10 );
	//	string strMeshName = "Mesh " + string( cBuf );
	//	pMesh->setName( strMeshName.c_str() );

	//	//shared_ptr<CGeomNode> pMeshT( new CGeomNode( strMeshName ) );

	//	osg::ref_ptr<osg::Vec3Array> pAry( new osg::Vec3Array );
	//	for( size_t j = 0; j < vPT.size(); ++ j )
	//		pAry->push_back( osg::Vec3( vPT[ j ].x, vPT[ j ].y, vPT[ j ].z ) );

	//	osg::ref_ptr<osg::DrawElementsUShort> triFace( new osg::DrawElementsUShort( GL_TRIANGLES, 0 ) );
	//	for( int j = 0; j < vIdx.size(); ++ j )
	//		triFace->push_back( vIdx[ j ] );

	//	osg::ref_ptr<osg::Vec4Array> pClrAry( new osg::Vec4Array );
	//	pClrAry->push_back( clr );

	//	osg::ref_ptr<osg::Geometry>	pGeometry( new osg::Geometry );
	//	pGeometry->setVertexArray( pAry.get() );
	//	pGeometry->addPrimitiveSet( triFace.get() );
	//	pGeometry->setColorArray( pClrAry );

	//	osgUtil::SmoothingVisitor::smooth( *pGeometry );
	//	osg::ref_ptr<osg::Geode> pLeafNode( new osg::Geode );
	//	pLeafNode->setName( "Leaf" );
	//	pLeafNode->addDrawable( pGeometry.get() );
	//	pMesh->addChild( pLeafNode );

	//	pProductOSG->addChild( pMesh );

	//	//pProductTree->AddChild( pMeshT );
	//}	
}
